import*as t from"../../../ui/legacy/legacy.js";import*as e from"../../../core/common/common.js";import*as o from"../../../core/platform/platform.js";var a=Object.freeze({__proto__:null,PortPadding:4,InputPortRadius:10,AudioParamRadius:5,LeftMarginOfText:12,RightMarginOfText:30,LeftSideTopPadding:5,BottomPaddingWithoutParam:6,BottomPaddingWithParam:8,ArrowHeadSize:12,GraphPadding:20,GraphMargin:20,TotalInputPortHeight:24,TotalOutputPortHeight:24,TotalParamPortHeight:14,NodeLabelFontStyle:"14px Segoe UI, Arial",ParamLabelFontStyle:"12px Segoe UI, Arial"});const d=t=>({x:0,y:15+24*t}),r=(t,e,o)=>{const{width:a,height:d}=e;return{x:a,y:d/2+24*(2*t-o+1)/2}},i=(t,e)=>({x:0,y:e+14*(t+1)-5});var s=Object.freeze({__proto__:null,calculateInputPortXY:d,calculateOutputPortXY:r,calculateParamPortXY:i});class n{id;type;numberOfInputs;numberOfOutputs;label;size;position;layout;ports;constructor(t,e){this.id=t.nodeId,this.type=t.nodeType,this.numberOfInputs=t.numberOfInputs,this.numberOfOutputs=t.numberOfOutputs,this.label=e,this.size={width:0,height:0},this.position=null,this.layout={inputPortSectionHeight:0,outputPortSectionHeight:0,maxTextLength:0,totalHeight:0},this.ports=new Map,this.initialize(t)}initialize(t){this.updateNodeLayoutAfterAddingNode(t),this.setupInputPorts(),this.setupOutputPorts()}addParamPort(t,e){const o=this.getPortsByType("Param").length,{x:a,y:d}=i(o,this.layout.inputPortSectionHeight);this.addPort({id:p(this.id,t),type:"Param",label:e,x:a,y:d}),this.updateNodeLayoutAfterAddingParam(o+1,e),this.setupOutputPorts()}getPortsByType(t){const e=[];return this.ports.forEach((o=>{o.type===t&&e.push(o)})),e}updateNodeLayoutAfterAddingNode(t){const e=24*Math.max(1,t.numberOfInputs)+5;this.layout.inputPortSectionHeight=e,this.layout.outputPortSectionHeight=24*t.numberOfOutputs,this.layout.totalHeight=Math.max(e+6,this.layout.outputPortSectionHeight);const o=c(this.label,"14px Segoe UI, Arial");this.layout.maxTextLength=Math.max(this.layout.maxTextLength,o),this.updateNodeSize()}updateNodeLayoutAfterAddingParam(t,e){const o=this.layout.inputPortSectionHeight+14*t+8;this.layout.totalHeight=Math.max(o,this.layout.outputPortSectionHeight);const a=c(e,"12px Segoe UI, Arial");this.layout.maxTextLength=Math.max(this.layout.maxTextLength,a),this.updateNodeSize()}updateNodeSize(){this.size={width:Math.ceil(12+this.layout.maxTextLength+30),height:this.layout.totalHeight}}setupInputPorts(){for(let t=0;t<this.numberOfInputs;t++){const{x:e,y:o}=d(t);this.addPort({id:u(this.id,t),type:"In",x:e,y:o,label:void 0})}}setupOutputPorts(){for(let t=0;t<this.numberOfOutputs;t++){const e=h(this.id,t),{x:o,y:a}=r(t,this.size,this.numberOfOutputs);if(this.ports.has(e)){const t=this.ports.get(e);if(!t)throw new Error(`Unable to find port with id ${e}`);t.x=o,t.y=a}else this.addPort({id:e,type:"Out",x:o,y:a,label:void 0})}}addPort(t){this.ports.set(t.id,t)}}const u=(t,e)=>`${t}-input-${e||0}`,h=(t,e)=>`${t}-output-${e||0}`,p=(t,e)=>`${t}-param-${e}`;class l{totalNumberOfNodes;constructor(){this.totalNumberOfNodes=0}generateLabel(t){t.endsWith("Node")&&(t=t.slice(0,t.length-4)),this.totalNumberOfNodes+=1;return`${t} ${this.totalNumberOfNodes}`}}let g;const c=(e,o)=>{if(!g){const t=document.createElement("canvas").getContext("2d");if(!t)throw new Error("Unable to create canvas context.");g=t}const a=g;a.save(),o&&(a.font=o);const d=t.UIUtils.measureTextWidth(a,e);return a.restore(),d};var m=Object.freeze({__proto__:null,NodeView:n,generateInputPortId:u,generateOutputPortId:h,generateParamPortId:p,NodeLabelGenerator:l,measureTextWidth:c});class I{id;type;sourceId;destinationId;sourcePortId;destinationPortId;constructor(t,e){const o=y(t,e);if(!o)throw new Error("Unable to generate edge port IDs");const{edgeId:a,sourcePortId:d,destinationPortId:r}=o;this.id=a,this.type=e,this.sourceId=t.sourceId,this.destinationId=t.destinationId,this.sourcePortId=d,this.destinationPortId=r}}const y=(t,e)=>{if(!t.sourceId||!t.destinationId)return console.error(`Undefined node message: ${JSON.stringify(t)}`),null;const o=h(t.sourceId,t.sourceOutputIndex),a=function(t,e){if(e===P.NodeToNode){const e=t;return u(t.destinationId,e.destinationInputIndex)}if(e===P.NodeToParam){const e=t;return p(t.destinationId,e.destinationParamId)}return console.error(`Unknown edge type: ${e}`),""}(t,e);return{edgeId:`${o}->${a}`,sourcePortId:o,destinationPortId:a}};var P;!function(t){t.NodeToNode="NodeToNode",t.NodeToParam="NodeToParam"}(P||(P={}));var f=Object.freeze({__proto__:null,EdgeView:I,generateEdgePortIdsByData:y,get EdgeTypes(){return P}});class b extends e.ObjectWrapper.ObjectWrapper{contextId;nodes;edges;outboundEdgeMap;inboundEdgeMap;nodeLabelGenerator;paramIdToNodeIdMap;constructor(t){super(),this.contextId=t,this.nodes=new Map,this.edges=new Map,this.outboundEdgeMap=new o.MapUtilities.Multimap,this.inboundEdgeMap=new o.MapUtilities.Multimap,this.nodeLabelGenerator=new l,this.paramIdToNodeIdMap=new Map}addNode(t){const e=this.nodeLabelGenerator.generateLabel(t.nodeType),o=new n(t,e);this.nodes.set(t.nodeId,o),this.notifyShouldRedraw()}removeNode(t){this.outboundEdgeMap.get(t).forEach((t=>this.removeEdge(t))),this.inboundEdgeMap.get(t).forEach((t=>this.removeEdge(t))),this.nodes.delete(t),this.notifyShouldRedraw()}addParam(t){const e=this.getNodeById(t.nodeId);e?(e.addParamPort(t.paramId,t.paramType),this.paramIdToNodeIdMap.set(t.paramId,t.nodeId),this.notifyShouldRedraw()):console.error("AudioNode should be added before AudioParam")}removeParam(t){this.paramIdToNodeIdMap.delete(t)}addNodeToNodeConnection(t){const e=new I(t,P.NodeToNode);this.addEdge(e)}removeNodeToNodeConnection(t){if(t.destinationId){const e=y(t,P.NodeToNode);if(!e)throw new Error("Unable to generate edge port IDs");const{edgeId:o}=e;this.removeEdge(o)}else this.outboundEdgeMap.get(t.sourceId).forEach((t=>this.removeEdge(t)))}addNodeToParamConnection(t){const e=new I(t,P.NodeToParam);this.addEdge(e)}removeNodeToParamConnection(t){const e=y(t,P.NodeToParam);if(!e)throw new Error("Unable to generate edge port IDs");const{edgeId:o}=e;this.removeEdge(o)}getNodeById(t){return this.nodes.get(t)||null}getNodes(){return this.nodes}getEdges(){return this.edges}getNodeIdByParamId(t){return this.paramIdToNodeIdMap.get(t)||null}addEdge(t){const e=t.sourceId;this.outboundEdgeMap.hasValue(e,t.id)||(this.edges.set(t.id,t),this.outboundEdgeMap.set(e,t.id),this.inboundEdgeMap.set(t.destinationId,t.id),this.notifyShouldRedraw())}removeEdge(t){const e=this.edges.get(t);e&&(this.outboundEdgeMap.delete(e.sourceId,t),this.inboundEdgeMap.delete(e.destinationId,t),this.edges.delete(t),this.notifyShouldRedraw())}notifyShouldRedraw(){this.dispatchEventToListeners("ShouldRedraw",this)}}var N=Object.freeze({__proto__:null,GraphView:b});var x=Object.freeze({__proto__:null,GraphManager:class{graphMapByContextId=new Map;createContext(t){const e=new b(t);this.graphMapByContextId.set(t,e)}destroyContext(t){if(!this.graphMapByContextId.has(t))return;this.graphMapByContextId.get(t)&&this.graphMapByContextId.delete(t)}hasContext(t){return this.graphMapByContextId.has(t)}clearGraphs(){this.graphMapByContextId.clear()}getGraph(t){return this.graphMapByContextId.get(t)||null}}});export{f as EdgeView,x as GraphManager,a as GraphStyle,N as GraphView,s as NodeRendererUtility,m as NodeView};
